package com.gz.moreaseManager.config;

import com.gz.moreaseManager.sys.entity.RoleMenu;
import com.gz.moreaseManager.sys.service.IMenuService;
import com.gz.moreaseManager.sys.service.IRoleMenuService;
import com.gz.moreaseManager.utils.UtilTool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Component
public class SelfSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

	private final IRoleMenuService roleMenuService;
	/**
	 * 储存权限关系数据，可放在缓存中
	 */
	private Map<String, List<ConfigAttribute>> configAttributeMap = null;

	@Autowired
	public SelfSecurityMetadataSource(IRoleMenuService roleMenuService) {
		this.roleMenuService = roleMenuService;
	}

	/**
	 * 加载权限表中所有权限
	 */
	public void loadResourceDefine() {
		configAttributeMap = new HashMap<>();
		List<ConfigAttribute> configAttributes;
		List<RoleMenu> roleMenuList = roleMenuService.findAllRoleMenuList();
		for (RoleMenu roleMenu : roleMenuList) {
			if (UtilTool.isBlank(roleMenu.getRoleName()) || UtilTool.isBlank(roleMenu.getMenuLink()))
				continue;
			configAttributes = configAttributeMap.get(roleMenu.getMenuLink());
			if (configAttributes == null)
				configAttributes = new ArrayList<>();
			configAttributes.add(new SecurityConfig(roleMenu.getRoleName()));
			configAttributeMap.put(roleMenu.getMenuLink(), configAttributes);
		}
	}

	/**
	 * 判断请求地址是否在权限表中
	 *
	 * @param object 用户请求信息
	 * @return 可以请求的角色集合
	 */
	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) {
		if (configAttributeMap == null) loadResourceDefine();
		HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
		AntPathRequestMatcher matcher;
		Set<String> keySet = configAttributeMap.keySet();
		for (String requestLink : keySet) {
			matcher = new AntPathRequestMatcher(requestLink);
			if (matcher.matches(request)) {
				return configAttributeMap.get(requestLink);
			}
		}
		return null;
	}

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return null;
	}

	@Override
	public boolean supports(Class<?> clazz) {
		return true;
	}
}